package com.zhike.utils.manager;

import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.Set;
import java.util.concurrent.ConcurrentMap;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.eva.epc.common.util.CommonUtils;
import com.zhike.mobileimsdk.server.processor.OnlineProcessor;
import com.zhike.mobileimsdk.server.processor.OnlineUserManager;
import com.zhike.service.user.IUserService;

/**
 * 用户在线状态逻辑管理器.
 * 
 */
@Slf4j
@Component
public class UsersStatusManager {
  @Resource
  private IUserService userService;

  /**
   * 用户是否在线.
   * 
   * 
   * @param uid 此参数为必须项
   * @return
   */
  public boolean isOnline(String uid) {
    return OnlineProcessor.isOnline(uid);
  }

  /**
   * 用户上线.
   * 
   * @param uidOrMail
   * @param user_id
   * @param osType    osType 登录设备
   */
  public void userOnline(String user_id, String osType) {
    // 将用户上线状态更新至用户数据库表中
    userOnlineToDB(user_id, osType);
  }

  /**
   * 用户下线.
   * 
   * @param uidOrMail
   */
  public void userOffline(String uidOrMail, String osType) {
    // 将用户离线状态更新至数据库表中
    userOfflineToDB(uidOrMail, osType);
  }

  public ConcurrentMap<String, Channel> getLiveUsers() {
    return OnlineProcessor.getInstance().getOnlineSessions();
  }

  // 全服在线用户列表
  public Set<String> getAllLiveUsers() {
    return OnlineUserManager.getInstance().getOnlineUsers();
  }

  public Long getAllLiveUsersCount() {
    return OnlineUserManager.getInstance().getOnlineUsersCount();
  }

  public void printLiveUsers() {
    Set<String> keys = getLiveUsers().keySet();
    log.info("[ZKIMChat]<----------当前在线用户共(" + keys.size() + ")人--------->");
    // for (String key : keys) {
    // Device device = deviceInfoCacheProvider.get(key);
    // if (device != null) {
    // device.getFakeUid();
    // UserInfo4Cache uc = usersInfoCacheProvider.get(device.getFakeUid());
    // StringBuffer userStr = new StringBuffer();
    // if (uc != null) {
    // userStr.append("userID:").append(uc.getFakeUid()).append("昵称：").append(uc.getNickName());
    // }
    // log.debug("uidOrDevice=" + key + ",user=" + userStr.toString());
    // }

    // }
  }

  // ----------------------------------------------------------------------------------------
  /**
   * 无条件重置用户列中的“是否在线”字段为“不在线”.
   * 
   * <p>
   * 通常会在服务端重启时无条件重置一次，保证服务端因意外终止时未及时重置的用户在线状态能被正确重置.
   */
  private boolean resetUserOnlieStatusToDB() {
    boolean sucess = false;
    try {
      userService.updateOnlineStatusAll();
      sucess = true;
    } catch (Exception e) {
      if (e instanceof IllegalArgumentException) {
        log.debug("[ZKIMChat]resetUserOnlieStatusToDB()时，影响行数为0，" +
            "原因应是之前的用户在线状态已被全部正常复位，请忽略本条Log哦。(DEBUG INFO：" + e.getMessage() + ")");
      } else {
        log.warn("[ZKIMChat]resetUserOnlieStatusToDB()用户在线状态时有问题哦，", e);
      }
    }
    return sucess;
  }

  /**
   * 将用户上线状态更新至用户数据库表中.
   * 
   * @param uidOrMail
   * @return
   */
  private boolean userOnlineToDB(String uid, String osType) {
    return _userIsOnlineStatusUpdateToDB(true, uid, osType);
  }

  /**
   * 将用户离线状态更新至数据库表中.
   * 
   * @param uidOrMail
   * @return
   */
  private boolean userOfflineToDB(String uidOrMail, String osType) {
    return _userIsOnlineStatusUpdateToDB(false, uidOrMail, osType);
  }

  private boolean _userIsOnlineStatusUpdateToDB(boolean online, String uidOrMail, String osType) {
    boolean sucess = false;
    try {
      // 不支持的平台
      if (StringUtils.isNotBlank(osType)) {
        userService.updateOnlineStatus(online, CommonUtils.isEmail(uidOrMail), uidOrMail, osType);
        sucess = true;
      }
    } catch (Exception e) {
      if (e instanceof IllegalArgumentException) {
        log.debug("[ZKIMChat]_userIsOnlineStatusUpdateToDB()时，影响行数为0，" +
            "原因应是用户" + uidOrMail + "的在线状态已被正常复位，请忽略本条Log哦。(DEBUG INFO：" + e.getMessage() + ")");
      } else {
        log.warn("[ZKIMChat]_userIsOnlineStatusUpdateToDB()用户在线状态时有问题哦，", e);
      }
    }
    return sucess;
  }
}
